package com.hzy.fivepalace.wx.service;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.hutool.core.util.DesensitizedUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.hzy.fivepalace.common.type.UserStatusTypeEnums;
import com.hzy.fivepalace.common.type.VipTypeEnums;
import com.hzy.fivepalace.common.util.ResponseUtil;
import com.hzy.fivepalace.common.util.TableDataInfo;
import com.hzy.fivepalace.db.dao.DtsPointsDetailMapper;
import com.hzy.fivepalace.db.dao.DtsWithdrawRecordsMapper;
import com.hzy.fivepalace.db.dao.ex.AppUserCommissionDetaiMapperEx;
import com.hzy.fivepalace.db.dao.ex.DtsUserMapperEx;
import com.hzy.fivepalace.db.domain.DtsPointsDetail;
import com.hzy.fivepalace.db.domain.DtsPointsDetailExample;
import com.hzy.fivepalace.db.domain.DtsUser;
import com.hzy.fivepalace.db.domain.DtsWithdrawRecordsWithBLOBs;
import com.hzy.fivepalace.db.service.DtsUserService;
import com.hzy.fivepalace.db.vo.wx.*;
import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 用户服务中心
 */
@Service
public class WxUserService {


    @Resource
    private DtsWithdrawRecordsMapper dtsWithdrawRecordsMapper;

    @Autowired
    private DtsUserService userService;

    @Autowired
    private WxMaService wxMaService;

    @Resource
    private AppUserCommissionDetaiMapperEx userCommissionDetaiMapperEx;

    @Resource
    private DtsUserMapperEx dtsUserMapperEx;

    @Resource
    private DtsPointsDetailMapper dtsPointsDetailMapper;

    @Resource
    private Redisson redisson;

    /**
     * 资源映射路径
     */
    @Value("${sys-config.profile}")
    private String profile;

    /**
     * 资源映射路径前缀
     */
    @Value("${sys-config.profile-handler}")
    private String profileHandler;

    /**
     * 域名
     */
    @Value("${sys-config.domain}")
    private String domain;

    @Value("${hzy.wx.app-id}")
    private String appId;

    /**
     * 获取用户团队列表
     *
     * @param page
     * @param size
     * @param userId
     * @return
     */
    public TableDataInfo getUserTeamList(Integer page, Integer size, Integer userId) {
        Page p = PageHelper.startPage(page, size);
        List<WxUserTeamVo> list = dtsUserMapperEx.getUserTeamList(userId);
        if (CollectionUtils.isEmpty(list)) {
            list = new ArrayList<>();
        } else {
            list.forEach(item -> {
                if (null != item.getVipType() && null == VipTypeEnums.getEnum(item.getVipType())) {
                    item.setVipType(null);
                }
            });
        }

        Map<String, Object> append = new HashMap<>();
        append.put("teamSumCommission", dtsUserMapperEx.getTeamSumCommission(userId));//团队嗨币总数
        append.put("monthTeamSumCommission", dtsUserMapperEx.getMonthTeamSumCommission(userId));//团队月嗨币总数
        return TableDataInfo.getDataTable(list, p.getTotal(), append);
    }

    /**
     * 获取用户积分明细列表
     *
     * @param page
     * @param size
     * @param userId
     * @return
     */
    public TableDataInfo getUserPointsDetailList(Integer page, Integer size, Integer userId) {
        DtsPointsDetailExample query = new DtsPointsDetailExample();
        query.setOrderByClause("add_time desc,id desc");
        query.createCriteria().andUserIdEqualTo(userId);
        Page p = PageHelper.startPage(page, size);
        List<DtsPointsDetail> list = dtsPointsDetailMapper.selectByExample(query);
        if (CollectionUtils.isEmpty(list)) {
            list = new ArrayList<>();
        } else {
            list.forEach(item -> {
                //不返回相关用户id
                item.setUserId(null);
                item.setToUserId(null);
            });
        }
        return TableDataInfo.getDataTable(list, p.getTotal());
    }

    /**
     * 获取用户提现记录列表
     *
     * @param page
     * @param size
     * @param userId
     * @return
     */
    public TableDataInfo getUserWithdrawRecordsList(Integer page, Integer size, Integer userId) {

        Page p = PageHelper.startPage(page, size);
        List<WxUserWithdrawRecordsDto> list = dtsWithdrawRecordsMapper.getUserWithdrawRecordsList(userId);

        if (CollectionUtils.isEmpty(list)) {
            list = new ArrayList<>();
        }
        return TableDataInfo.getDataTable(list, p.getTotal());
    }

    /**
     * 获取用户嗨币明细列表
     *
     * @param page
     * @param size
     * @param userId
     * @return
     */
    public TableDataInfo getUserCommissionDetailList(Integer page, Integer size, Integer userId) {
        Page p = PageHelper.startPage(page, size);
        List<WxUserCommissionDetailDto> list = userCommissionDetaiMapperEx.getUserCommissionDetailList(userId);
        if (CollectionUtils.isEmpty(list)) {
            list = new ArrayList<>();
        }
        return TableDataInfo.getDataTable(list, p.getTotal());
    }

    /**
     * 获取用户嗨币信息
     *
     * @param userId
     * @return
     */
    public Object getUserCommissionInfo(Integer userId) {
        DtsUser user = userService.selectById(userId);
        if (null == user) {
            return ResponseUtil.unlogin("账号不存在");
        }
        Map<String, Object> result = new HashMap<>();
        result.put("commission", user.getCommission());//当前可提现嗨币
        result.put("commissionSumCount", userCommissionDetaiMapperEx.getUserCommissionSumCount(userId));//嗨币总数
        result.put("toDayCommissionSumCount", userCommissionDetaiMapperEx.getUserToDayCommissionSumCount(userId));//今日嗨币
        result.put("dividend", userCommissionDetaiMapperEx.getUserDividendSumCount(userId));//分红
        result.put("managementAward", userCommissionDetaiMapperEx.getUserManagementAwardSumCount(userId));//管理奖
        result.put("monthCommissionSumCount", userCommissionDetaiMapperEx.getUserMonthCommissionSumCount(userId));//月嗨币总数
        return ResponseUtil.ok(result);
    }

    /**
     * 提现
     *
     * @param dto
     * @param userId
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public Object submitWithdraw(WxSubmitWithdrawDto dto, Integer userId) {
        RLock lock = redisson.getLock("wx_submitWithdraw_" + userId);
        if (lock.isLocked()) {
            return ResponseUtil.frequent();
        }
        lock.lock(30, TimeUnit.SECONDS);


        if (null == dto.getAmount()) {
            lock.unlock();
            return ResponseUtil.fail("请填写提现金额");
        }
        if (StringUtils.isBlank(dto.getAlipayName())) {
            lock.unlock();
            return ResponseUtil.fail("请填写支付宝真实姓名");
        }
        if (StringUtils.isBlank(dto.getAlipayAccount())) {
            lock.unlock();
            return ResponseUtil.fail("请填写支付宝账号");
        }
        if (dto.getAmount().compareTo(new BigDecimal("1")) < 0) {
            lock.unlock();
            return ResponseUtil.fail("最低提现1元");
        }
        DtsUser user = userService.selectById(userId);
        if (null == user) {
            lock.unlock();
            return ResponseUtil.unlogin("账号不存在");
        }

        if (user.getCommission().compareTo(dto.getAmount()) < 0) {
            lock.unlock();
            return ResponseUtil.fail("嗨币不足");
        }

        //扣除用户余额
        if (dtsUserMapperEx.subtractUserCommission(userId, dto.getAmount()) <= 0) {
            lock.unlock();
            return ResponseUtil.fail("嗨币不足");
        }
        //新增提现记录
        DtsWithdrawRecordsWithBLOBs withdrawRecords=new DtsWithdrawRecordsWithBLOBs();
        withdrawRecords.setUserId(userId);
        withdrawRecords.setAddTime(LocalDateTime.now());
        withdrawRecords.setUserPhone(user.getMobile());
        withdrawRecords.setAmount(dto.getAmount());
        withdrawRecords.setAlipayAccount(dto.getAlipayAccount());
        withdrawRecords.setAlipayName(dto.getAlipayName());
        withdrawRecords.setStatus(0);//待审核
        dtsWithdrawRecordsMapper.insertSelective(withdrawRecords);


        lock.unlock();
        return ResponseUtil.ok("提现申请已提交,请等待审核");
    }

    /**
     * 获取用户详情信息
     *
     * @param userId
     * @return
     */
    public Object getUserInfo(Integer userId) {
        DtsUser user = userService.selectById(userId);
        if (null == user) {
            return ResponseUtil.unlogin("账号不存在");
        }
        //账号状态判断
        if (user.getDeleted()) {
            return ResponseUtil.unlogin("账号已被删除");
        }
        if (UserStatusTypeEnums.DISABLE.getId().equals(user.getStatus())) {
            return ResponseUtil.unlogin("账号已被禁用");
        }
        if (UserStatusTypeEnums.CANCEL.getId().equals(user.getStatus())) {
            return ResponseUtil.unlogin("账号已注销");
        }
        if (null != user.getVipType() && null == VipTypeEnums.getEnum(user.getVipType())) {
            user.setVipType(null);
        }

        if (StringUtils.isBlank(user.getRecodeCodeImgUrl())) {//如果推荐码图片地址入空那就去生成
            try {
                String recodeCodeImgUrl = null;
                //创建微信小程序二维码
                File file = wxMaService.switchoverTo(appId).getQrcodeService().createWxaCodeUnlimit(user.getRecodeCode(), "pages/index/index");
                String realFileName = System.currentTimeMillis() + ".png";
                BufferedImage read = ImageIO.read(file);
                if (read != null) {
                    ImageIO.write(read, "png", new File(profile + "/re_code_file/" + realFileName));//有就写入
                    recodeCodeImgUrl = domain + profileHandler + "/re_code_file/" + realFileName;
                }
                if (!StringUtils.isBlank(recodeCodeImgUrl)) {
                    DtsUser userUpd = new DtsUser();
                    userUpd.setRecodeCodeImgUrl(recodeCodeImgUrl);
                    userUpd.setId(userId);
                    userService.updateById(userUpd);
                    user.setRecodeCodeImgUrl(recodeCodeImgUrl);
                }
            } catch (Exception e) {

            }
        }
        WxUserInfoDto dto = new WxUserInfoDto();
        BeanUtils.copyProperties(user, dto);
        //手机号脱敏返回
        dto.setMobile(DesensitizedUtil.mobilePhone(dto.getMobile()));
        return ResponseUtil.ok(dto);
    }
}
